class FeatureSelector:
    def __init__(self):
        self.selected_features = []
        self.selector = None
        
    def select_features(self, X, y, method='random_forest', k=50):
        """特征选择"""
        if method == 'random_forest':
            from sklearn.ensemble import RandomForestClassifier
            model = RandomForestClassifier(n_estimators=100, random_state=42)
            model.fit(X, y)
            importances = model.feature_importances_
            indices = np.argsort(importances)[::-1][:k]
            self.selected_features = X.columns[indices]
            
        elif method == 'mutual_info':
            from sklearn.feature_selection import mutual_info_classif
            mi_scores = mutual_info_classif(X, y)
            indices = np.argsort(mi_scores)[::-1][:k]
            self.selected_features = X.columns[indices]
            
        elif method == 'pca':
            pca = PCA(n_components=k)
            X_pca = pca.fit_transform(X)
            self.pca = pca
            return X_pca
            
        return X[self.selected_features]
    
    def visualize_features(self, X, y, method='tsne'):
        """特征可视化"""
        if method == 'tsne':
            tsne = TSNE(n_components=2, random_state=42)
            X_embedded = tsne.fit_transform(X)
            
        elif method == 'pca':
            pca = PCA(n_components=2)
            X_embedded = pca.fit_transform(X)
        
        plt.figure(figsize=(12, 8))
        scatter = plt.scatter(X_embedded[:, 0], X_embedded[:, 1], c=y, cmap='viridis', alpha=0.7)
        plt.colorbar(scatter)
        plt.title(f'{method.upper()} Visualization of Feature Space')
        plt.xlabel('Component 1')
        plt.ylabel('Component 2')
        plt.show()

# 特征选择示例
X = features_df.drop(['file_name', 'fault_type', 'fault_size', 'load_condition'], axis=1)
y = LabelEncoder().fit_transform(features_df['fault_type'])

selector = FeatureSelector()
X_selected = selector.select_features(X, y, method='random_forest', k=30)
selector.visualize_features(X_selected, y, method='tsne')
